interface StorageOptionsInterface<K = string> {
  local: boolean;
  getKeyHandler: (key: K) => string;
}

export default class Storage<K = string> {
  constructor(options?: Partial<StorageOptionsInterface<K>>) {
    const defaults: StorageOptionsInterface<K> = {
      local: true,
      getKeyHandler(key: K) {
        return key as string;
      },
    };
    const { local, getKeyHandler } = { ...defaults, ...options };
    this.storeHandler = local ? localStorage : sessionStorage;
    this.getKeyHandler = getKeyHandler;
  }
  storeHandler: typeof window.localStorage | typeof window.sessionStorage;
  getKeyHandler: StorageOptionsInterface<K>['getKeyHandler'];
  get(targetKey: K) {
    const key = this.getKeyHandler(targetKey);
    const orignalStore = this.storeHandler.getItem(key);
    const { value } = JSON.parse(orignalStore || '{}');
    return value;
  }
  set(targetKey: K, value: any) {
    const key = this.getKeyHandler(targetKey);
    this.storeHandler.setItem(key, JSON.stringify({ key, value }));
  }
  remove(targetKey: K) {
    const key = this.getKeyHandler(targetKey);
    this.storeHandler.removeItem(key);
  }
}
